import csv, StringIO, logging
from google.appengine.ext import webapp
#from process_data import processUploadedCompaction
from django.utils import simplejson
#from ft_table import FtTable
#import dlz_config as dc
from google.appengine.api import users
#from record import Record
from google.appengine.api import memcache

from google.appengine.ext.webapp import template
import datetime

import model, urllib2, os
from errors import *
from google.appengine.ext import db
#import table_schema, csv_uploader
from gae_db_manager import GaeDbManager

def batch_update(records, table_model, change_table_id, skip_fields):
    '''
    batch update table records in gae_table
    '''
    #make sure nothing is from the cache
    memcache.flush_all()
    #check if the file  format is OK
    q = model.dlz_table_schema.all().filter('table_name = ', table_model.kind()).filter('exportable = ', 'YES').order('field_position')
    row1 = []
    row2 = []
    for r in q:
        row1.append(r.field_name)
        row2.append(r.field_label)
    row1.append('google_key')
    row2.append('google_key')
    header = records[0]
    #check if fields are correct
    for fld in header:
        if fld in row1:
            pass
        else:
            
            logging.warning('Field "%s" is not a system defined field.' % fld)
    for fld in row1:
        if fld in header:
            pass
        else:
            logging.warning('Field "%s" is not in uploaded table' % fld)
            
    
    #check if rowid is present
    if 'google_key' in header:
        pass
    else:
        logging.fatal('google_key is not found in uploaded table')
        return {'success': False, 'message': ''}
    logging.info('Uploading CSV file to table: %s' % table_model.kind())
    data = records[2:]
    for r_uploaded in data:
        #only update the testing form, project form is ignored.
        r_uploaded = dict(zip(header, r_uploaded))
        r = db.get(r_uploaded['google_key'])
        
        for fld in header:
            if fld in skip_fields:
                pass
            else:
                v = r_uploaded[fld]
                old_v = getattr(r, fld)
                
                
                if v:
                    if type(getattr(r, fld))==datetime.datetime:
                        pass
                    elif type(getattr(r, fld))==db.FloatProperty:
                        v = float(v)
                    elif type(getattr(r, fld))==db.IntegerProperty:
                        v = int(v)
                else:
                    v = None
                     
                logging.info('%s vs. %s' % (v, old_v))
                if v==old_v:
                    logging.info('no change: %s=%s' % (fld, v))
                else:
                    setattr(r, fld, v)
                    logging.info('change %s : %s=>%s' % (fld,old_v, v))
        r.put()
    
def update_asphalt_test(records):
    '''
    update the compaction_test table with the records
    '''
    skip_fields = ['google_key', 'project_number', 'client_name', 'project_name', 'form_date']
    batch_update(records, model.asphalt_test, None, skip_fields)
    
def update_compaction_test(records):
    '''
    update the compaction_test table with the records
    '''
    skip_fields = ['google_key', 'project_number', 'client_name', 'project_name', 'form_date']
    batch_update(records, model.compaction_test, None, skip_fields)

    
    
            
class UploadHandler(webapp.RequestHandler):
    def get(self):
        path = os.path.join(os.path.dirname(__file__), 'template/upload.html')
        options = 'Email dlz_project_list compaction_test compaction_form dlz_connection dlz_config asphalt_form asphalt_test'.split()
        self.response.out.write(template.render(path, {'options': options}))
    
    def post(self):
        file_content = self.request.get('file')
        file_type = self.request.get('file_type')
        action = self.request.get('action')
        if action=='upload-raw-table':
            empty = self.request.get('empty')
            tbl = self.request.get('table')
            gdm = GaeDbManager(tbl)
            if empty=='yes':gdm.empty()
            gdm.insert_csv(file_content)
            self.response.out.write('%s is uploaded' % tbl)
        elif action=='update_compaction_test':
            self.update_compaction_test(file_content)
            # self.response.headers["Content-Type"] = "application/json"  
            #if not turned off the content type, it is not working with extjs
            self.response.out.write(simplejson.dumps({'success': True}))
        elif action=='update_asphalt_test':
            self.update_asphalt_test(file_content)
            # self.response.headers["Content-Type"] = "application/json"  
            #if not turned off the content type, it is not working with extjs
            self.response.out.write(simplejson.dumps({'success': True}))
        elif action=='update_dlz_table_schema':
            from google.appengine.ext.db import StringProperty, IntegerProperty
            fields = []
            for fld in model.dlz_table_schema.fields():
                d =  {'name': fld, 'header': fld,'dataIndex': fld, 'exportable': 'YES', 'formatFn': lambda v: v}
                if type(getattr(model.dlz_table_schema, fld))==StringProperty:
                    d['type'] = 'String'
                    d['conFn'] = str
                elif type(getattr(model.dlz_table_schema, fld))==IntegerProperty:
                    d['type'] = 'int'
                    d['conFn'] = int
                fields.append(d)
            tbl = 'dlz_table_schema'
            logging.info(fields)
            gdm = GaeDbManager(tbl, fields)
            gdm.empty()
            gdm.insert_csv(file_content)
            #update_dlz_table_schema(file_content)
            self.response.out.write('table schema updated!')
        elif action=='update_asphalt_test_project_info':
            self.update_test_table(file_content, 'asphalt_test', ['project_number', 'project_name', 'client_name', 'form_date'])
            self.response.out.write('project info for asphalt_test is updated')
        elif action=='update_compaction_test_project_info':
            self.update_test_table(file_content, 'compaction_test', ['project_number', 'project_name', 'client_name', 'form_date'])
            self.response.out.write('project info for asphalt_test is updated')
    
    def update_compaction_test(self, csv_file):
        '''pass a string of a csv file and parse it into json format'''
        gdm = GaeDbManager('compaction_test')
        skip_fields = ['google_key', 'project_number', 'client_name', 'project_name', 'form_date']
        fields = []
        for v in gdm.fields:
            if v['name'] in skip_fields or v['exportable']=='NO':
                pass
            else:
                fields.append(v)
        gdm.fields = fields        
        gdm.update_csv(csv_file)

    def update_asphalt_test(self, csv_file):
        '''pass a string of a csv file and parse it into json format'''
        gdm = GaeDbManager('asphalt_test')
        skip_fields = ['google_key', 'project_number', 'client_name', 'project_name', 'form_date']
        fields = []
        for v in gdm.fields:
            if v['name'] in skip_fields or v['exportable']=='NO':
                pass
            else:
                fields.append(v)
        gdm.fields = fields        
        gdm.update_csv(csv_file)
#        fhandler = StringIO.StringIO(csv_file)
#        reader = csv.reader(fhandler)
#        results = []
#        for l in reader:
#            results.append(l)
#        fhandler.close()
##        logging.info(results)
#        
#        update_asphalt_test(results)
    
    def update_test_table(self, csv_file, table_name, flds):
        '''update test talbe with csv file'''
        gdm = GaeDbManager(table_name)
        fields = []
        for v in gdm.fields:
            if v['name'] in flds:
                fields.append(v)
        gdm.fields = fields        
        gdm.update_csv(csv_file)